<?php
/**
 * 用户 servers
 */

namespace App\Services\Member;

use App\Models\Member\Follow;
use App\Models\Member\Member;
use App\Models\Member\HubSettings;
use App\Models\Member\Tag;
use App\Models\Member\Friend;
use App\Models\Member\TagMember;
use App\Models\Member\Collect;
use App\Models\Order\Order;
use App\Models\Square\Feeds;
use App\Models\Square\FeedViewByUser;
use App\Services\Com\ConfigService;
use App\Services\Com\GatherService;
use App\Services\Com\ProcessService;
use App\Services\Com\UtilService;
use App\Services\Easemob\UserAuth as EasemobUserAuth;
use App\Services\Group\GroupService;
use App\Services\Square\FeedsService;
use App\Services\Easemob\UserAuth;
use App\Services\Easemob\Messages;
use App\Models\Member\NotifySettings;
use App\Services\Talking\TalkingService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class MemberService
{
    /**
     * 查询某个业务是否已经被某人收藏,支持一人多条
     * @param array $service_uuids 业务uuid
     * @param int $place 业务 place
     * @param string $uuid 某人uuid 
     * @return 
     * @throws \Exception
     */
    public static function collectByMemberUuids(array $service_uuids = [], int $place = 0, string $member_uuid = '')

    {
        try {
            $res = Collect::whereIn("service_uuid", $service_uuids)
                    ->where("place", '=', $place)
                    ->where('member_uuid', '=', $member_uuid)->groupBy('member_uuid')->get();
            
            $res_arr = [];   
            if(!empty($res)){
                $res_db_arr = $res->toArray();
                foreach ($res_db_arr as $key => $value) {
                    $res_arr[$value['service_uuid']] = $value;
                }
            }
            return $res_arr;

        } catch (\Exception $e) {
            throw new \Exception($e->getLine().$e->getMessage());
        }
    }

    /**
     * 根据环信用户id返回migo uuid
     * @param array 
     * @return 
     * @throws \Exception
     */
    public static function userInfoByImUsername(string $im_member_username = '')
    {
        try {
            $res = Member::select('*')->whereRaw("MD5(uuid) = ? ", [$im_member_username])->first();
            $res_arr = [];
            if(!empty($res)){
                $res_arr = $res->toArray();
            }
            return $res_arr;
        } catch (\Exception $e) {
            throw new \Exception($e->getLine().$e->getMessage());
        }
    }

    /**
     * 批量返回用户的动态
     * @param array $member_uuids ['aa-bb','cc-dd']
     * @return array(1) {
                  ["6c261036-681c-4180-80af-cc0266b82a69"]=>
                  int(1)
                }

     * @throws \Exception
     */
    public static function usersTrendsMtl(array $member_uuids = [])
    {
        try {
            $res = FeedViewByUser::select(DB::raw('count(*) as count, member_uuid'))
                ->whereIn('member_uuid', $member_uuids)->groupBy('member_uuid')->get();
            
            $res_arr = [];   
            if(!empty($res)){
                $res_db_arr = $res->toArray();
                foreach ($res_db_arr as $key => $value) {
                    $res_arr[$value['member_uuid']] = $value['count'];
                }
            }
            return $res_arr;

        } catch (\Exception $e) {
            
            throw new \Exception($e->getLine().$e->getMessage());
        }
    }

    /**
     * 明星圈主统计
     * 统计某个时段内活跃
     * 公式：粉丝数+被打招呼数+动态发布数量+ 信息流+店铺+投票+活动
     */
    public static function memberActive()
    {
        // $start_time = date('2022-10-24 00:00:00', time());
        // $end_time   = date('2022-10-24 23:59:59', time());
        $start_time = date('Y-m-d 00:00:00', strtotime("-1 day"));
        $end_time   = date('Y-m-d 23:59:59', strtotime("-1 day"));
        $data       = date('Y-m-d', strtotime("-1 day"));
        
        //昨天粉丝量排名
        $fans_count = "SELECT count(*) as c,member_uuid  from member_follow WHERE 
                        created_at>='".$start_time."' AND created_at <='".$end_time."'
                        GROUP BY member_uuid order by c desc limit 100";
        //被打招呼数
        $say_hello = "
            SELECT count(*) as c,member_uuid  from member_message where  
            type=6 and created_at>='".$start_time."' AND created_at <='".$end_time."'
            GROUP BY member_uuid order by c desc limit 100
        ";
        // 动态发布数量
        $post = "
            SELECT count(*) as c,member_uuid  from posts where 
            created_at>='".$start_time."' AND created_at <='".$end_time."'
            GROUP BY member_uuid order by c desc limit 100
        ";
        $store = "
            SELECT count(*) as c,member_uuid  from store where 
            created_at>='".$start_time."' AND created_at <='".$end_time."'
            GROUP BY member_uuid order by c desc limit 100
        ";
        $vote = "SELECT count(*) as c,member_uuid  from vote where 
            created_at>='".$start_time."' AND created_at <='".$end_time."'
            GROUP BY member_uuid order by c desc limit 100
        ";
        $activity ="SELECT count(*) as c,member_uuid  from activity where 
            created_at>='".$start_time."' AND created_at <='".$end_time."'
            GROUP BY member_uuid order by c desc limit 100";
            
        //被打招呼数排名
        $fans_count_res = DB::select($fans_count);
        $say_hello_res = DB::select($say_hello);
        $post_res = DB::select($post);
        $store_res = DB::select($store);
        $vote_res = DB::select($vote);
        $activity_res = DB::select($activity);
        
        $active = [];
        foreach ($fans_count_res as $key => $value) {
            if(isset($active[$value->member_uuid])){
                $active[$value->member_uuid]['count'] += $value->c;
            }else{
                $active[$value->member_uuid]['count'] = $value->c;
            }
        }
        foreach ($say_hello_res as $key => $value) {
            if(isset($active[$value->member_uuid])){
                $active[$value->member_uuid]['count'] += $value->c;
            }else{
                $active[$value->member_uuid]['count'] = $value->c;
            }
        }
        foreach ($post_res as $key => $value) {
            if(isset($active[$value->member_uuid])){
                $active[$value->member_uuid]['count'] += $value->c;
            }else{
                $active[$value->member_uuid]['count'] = $value->c;
            }
        }
        foreach ($store_res as $key => $value) {
            if(isset($active[$value->member_uuid])){
                $active[$value->member_uuid]['count'] += $value->c;
            }else{
                $active[$value->member_uuid]['count'] = $value->c;
            }
        }
        foreach ($vote_res as $key => $value) {
            if(isset($active[$value->member_uuid])){
                $active[$value->member_uuid]['count'] += $value->c;
            }else{
                $active[$value->member_uuid]['count'] = $value->c;
            }
        }
        foreach ($activity_res as $key => $value) {
            if(isset($active[$value->member_uuid])){
                $active[$value->member_uuid]['count'] += $value->c;
            }else{
                $active[$value->member_uuid]['count'] = $value->c;
            }
        }
        $save_arr = [];
        foreach ($active as $a_key => $a_value) {
            $save_arr[] = ['uuid'=>Str::uuid(), 'member_uuid' => $a_key, 'count_date' => $data, 'active_count' => $a_value['count']];
        }

        DB::table('member_active')->insertOrIgnore($save_arr);
    }

    /**
     * 判断是不是我的好友批量
     * String $member_uuid = '',  用户uuid
     * String $friend_member_uuid = '',  好友uuid
     * int $is_muted = 0 , 是否禁言 1是
     * int $is_block = 0 是否拉黑 1是
     * 是返回 true
     */
    public static function batchIsMyFriend(String $member_uuid = '', array $friend_member_uuid = []):array
    {
        $model = Friend::where('member_uuid', '=', $member_uuid)->whereIn('friend_member_uuid', $friend_member_uuid);
        $res = $model->get();
        return $res->toArray();
    }


    /**
     * 判断是不是我的好友,没拉黑，没禁言
     * String $member_uuid = '',  用户uuid
     * String $friend_member_uuid = '',  好友uuid
     * int $is_muted = 0 , 是否禁言 1是
     * int $is_block = 0 是否拉黑 1是
     * 是返回 true
     */
    public static function isMyFriend(String $member_uuid = '', String $friend_member_uuid = '', int $is_muted = 0 )
    {
        // DB::connection()->enableQueryLog();
        //禁言
        $model = Friend::where('member_uuid', '=', $friend_member_uuid)->where('friend_member_uuid','=', $member_uuid);
        if($is_muted == 1){
            $model = $model->where('is_muted', $is_muted);
        }
        $res = $model->count();
        // $log = DB::getQueryLog();
        // var_dump([$log]);
        // die;

        return $res > 0 ? true : false;
    }

    /**
     * 判断是 有没有禁言我的好友
     * String $member_uuid = '',  用户uuid
     * String $friend_member_uuid = '',  好友uuid
     * int $is_block = 0 是否拉黑 1是
     * 是返回 true
     */
    public static function isMyFriendAndBlock(String $member_uuid = '', String $friend_member_uuid = '', int $is_block = 0 )
    {
        // DB::connection()->enableQueryLog();
        
        $model = Friend::where('member_uuid', '=', $friend_member_uuid)
                    ->where('friend_member_uuid','=', $member_uuid);
        //拉黑
        $model = $model->where('is_block', $is_block);

        $res = $model->count();
        // $log = DB::getQueryLog();
        // var_dump([$log]);
        // die;

        return $res > 0 ? true : false;
    }

    /**
     * 同步学校logo 背景
     */
    public static function sycnSchool()
    {
        set_time_limit(0);
        $sql = "
            
            SELECT
                s.`name`,
                s.`cn_name`,
                CONCAT('https://api.imhaiguiapp.com',( SELECT filepath FROM imhaigui1.imhg_image WHERE c.cover = imhaigui1.imhg_image.image_id )) as cover,
                CONCAT('https://api.imhaiguiapp.com',( SELECT filepath FROM imhaigui1.imhg_image WHERE c.logo = imhaigui1.imhg_image.image_id )) as logo
            FROM
                imhaigui1.imhg_school AS s
                INNER JOIN imhaigui1.imhg_college AS c ON s.school_id = c.school_id

            ";
            $res = DB::select($sql);

            foreach ($res as $key => $value) {
                
                $sql_img = "UPDATE `migo`.`school` SET `bg_img` = ?,
                `school_badge_img` = ?

                 WHERE `name` = ? and `cn_name` = ?";

                $res_img = DB::update($sql_img,[$value->cover,$value->logo,$value->name,$value->cn_name]);
                var_dump($res_img);
            }

            die;
        return $list;
    }

    /**
     * 同步注册用户到IM
     * https://api.imhaiguiapp.com
        var_dump(MemberService::sycnFeed());die;

     */
    public static function sycnFeed()
    {
        set_time_limit(0);
        $sql = "
            SELECT circle_id, content,album,video_id
            from  imhaigui1.imhg_circle where ctime<=1569584109 and voice_id=0 and `share` is null
            and circle_id not in(SELECT oid from imhaigui1.imhg_ad where aid=2) 
            and content not like '%[SITE_URL]%'
            limit 20000,2000
            ";
            $res = DB::select($sql);

            foreach ($res as $key => $value) {
                $album_arr = explode(',', $value->album);
                $album_arr_save = '';
                if(!empty($album_arr) && !empty($value->album)){
                    $sql_img = "select filepath from imhaigui1.imhg_image where FIND_IN_SET(imhg_image.image_id,'".$value->album."') ";
                    $res_img = DB::select($sql_img);
                    $album_arr_save_tmp = [];
                    foreach ($res_img as $key_i => $value_i) {
                        $album_arr_save_tmp[] = $value_i->filepath;
                    }
                    $album_arr_save = json_encode($album_arr_save_tmp);
                }
                $save_data[$value->circle_id]['circle_id'] = $value->circle_id;
                $save_data[$value->circle_id]['content'] = $value->content;
                $save_data[$value->circle_id]['album'] = $album_arr_save;
                $save_data[$value->circle_id]['video_id'] = $value->video_id;
            }

            // var_dump(count($save_data));die;

            $chunk_arr = array_chunk($save_data, 3, true);
            foreach ($chunk_arr as $ck_key => $ck_value) {
                $save_data_chunk = null;
                foreach ($ck_value as $c2_key => $c2_value) {
                    $save_data_chunk[] = 
                        [
                            'circle_id' => $c2_value['circle_id'],
                            'content' => $c2_value['content'],
                            'album' => $c2_value['album'],
                            'video_id' => $c2_value['video_id']
                        ];
                }
                
                DB::table('posts_old')->insertOrIgnore($save_data_chunk);
            }

            die;
        return $list;
    }

    /**
     * 同步注册用户到IM
     * 
        var_dump(MemberService::sycnUserToIm());die;
     */
    public static function sycnUserToIm()
    {
        set_time_limit(0);
        $list = Member::get();
        // $list = User::get(); //管理员同步
        $list_arr = $list->toArray();

        foreach ($list_arr as $key => $value) {
            
            // $value['uuid'] = $value['id'];//管理员同步
            // $value['nickname'] = $value['username'];//管理员同步

            $res1 = EasemobUserAuth::register($value);
            $res2 = EasemobUserAuth::metadata($value);
            var_dump($value['uuid'],$res1,$res2);
        }
        die;
        return $list;
    }

    /**
     * 获取我的标签及下面的用户头像
     * 
     * @param $type
     * @param $member_uuid
     * @return 
     * @throws \Exception
     */
    public static function getMyTag(int $type = 1, string $member_uuid = '', string $tag_uuid = '')
    {
        //返回权限设置
        $hub_settings = HubSettings::where('member_uuid', '=', $member_uuid)->select('*')->first();
        $hub_settings_data = null;
        if(!empty($hub_settings)){
            $hub_settings_data = json_decode($hub_settings['data'], true);
        }

        $query = Tag::where('type','=', $type)->where('member_uuid', '=', $member_uuid)->select('*');
        if(!empty($tag_uuid)){
            $query->where('uuid', $tag_uuid);
        }
        $query->orderBy('created_at', 'asc');
        $rows = $query->get();
        $list = null;

        foreach ($rows as $key => $value) {

            $tags = [];
            if($type == 1){
                $tags = $hub_settings_data['dispatch']['tag']['data'] ?? [];
            }else if($type == 2){
                $tags = $hub_settings_data['receive']['block_tag']['data'] ?? [];
            }

            $member_list = TagMember::with('member')->where('tag_uuid', '=', $value->uuid)->get();
            $member_list_arr = $member_list->toArray();
            $avatar_url = null;
            if(!empty($member_list_arr)){
                foreach ($member_list_arr as $m_key => $m_value) {
                    if(isset($m_value['member']['avatar_url'])){
                        $avatar_url[] = $m_value['member']['avatar_url'];
                    }
                }
            }
            $value['selected'] = in_array($value->uuid ?? '', $tags);
            $value['member_list'] = $avatar_url;
            $list[$key] = $value;
        }
    
        return $list;
    }

    /**
     * 通知权限默认设置
     * 
     * @param $member_uuid 
     * 总开关
     * 及时通讯：个人通知 私聊 talking通知 talking 
     * 圈子通知： 动态评论、动态点赞
     * 活动通知： 活动信息
     * @return 
     *          string(140) "{
                    "all": 1,
                    "im": 1,
                    "act": 1,
                    "circle": 1
                }"
                或者
                array(1) {
                      ["331442fb-b318-4ff2-be50-5f300a7a17ae"]=>
                      string(35) "{"all":1,"im":0,"act":0,"circle":1}"
                    }

     * @throws \Exception
     */
    public static function getNotifySettings(string $member_uuid = '')
    {
        $cache_key = config('cache.key_list.notifySettings').md5($member_uuid);
        $cache_data = Cache::get($cache_key);

        if(!empty($cache_data)){
            return $cache_data;
        }

        $res = null;
        $default = '{
                    "all": 1,
                    "im": 1,
                    "act": 1,
                    "circle": 1
                }';

        $rows_res = NotifySettings::where('member_uuid', '=', $member_uuid)->select('*')->first();
        
        if(empty($rows_res)){
            $res = json_decode($default, true);
        }elseif(!empty($rows_res)){
            $res_arr = $rows_res->toArray();
            $res = json_decode($res_arr['data'], true);
        }

        Cache::put($cache_key, $res, config('cache.ttl_30day'));
        return $res;
    }

    /**
     * 通知权限设置
     * 
     * @param $member_uuid 
     * @param $data {
                    "all": 1,
                    "im": 1,
                    "act": 1,
                    "circle": 1
                }
     * @return 
     * @throws \Exception
     */
    public static function updateNotifySettings(array $data = [], string $member_uuid = '')
    {
        //环信离线更新
        Messages::offlinePush($member_uuid, $data['im']);

        $data_str = json_encode($data);
        $res = NotifySettings::updateOrInsert(
            [
                'member_uuid' => $member_uuid
            ],
            [
                'data' => $data_str
            ]
        );
        $cache_key = config('cache.key_list.notifySettings').md5($member_uuid);
        $cache_data = Cache::delete($cache_key);
        return $res;
    }
    /**
     * hub权限默认设置
     * 
     * @param $member_uuid
     * @return 
     * @throws \Exception
     */
    public static function hubSettingsDefault()
    {
        $res = '{
                "dispatch": {
                    "open": "all",
                    "all": {
                        "data": null
                    },
                    "tag": {
                        "data": null
                    },
                    "user": {
                        "data": null
                    }
                },
                "receive": {
                    "open": "all",
                    "all": {
                        "data": null
                    },
                    "block_all": {
                        "data": null
                    },
                    "block_tag": {
                        "data": null
                    },
                    "block_user": {
                        "data": null
                    }
                }
            }';

        return json_decode($res);
    }

    /**
     * hub权限设置
     * 
     * @param $member_uuid 
     * @param $data
     * @return 
     * @throws \Exception
     */
    public static function hubSettingsUpdate(array $data = [], string $member_uuid = '')
    {
        
        $data_str = json_encode($data);
        
        $res = HubSettings::updateOrInsert(
            [
                'member_uuid' => $member_uuid
            ],
            [
                'data' => $data_str
            ]
        );

        return $res;
    }

    /**
     * 返回在线的用户，支持多个
     * @param array $member_uuids ['aa-bb','cc-dd']
     * @return array(1) {
                  ["6c261036-681c-4180-80af-cc0266b82a69"]=>
                  int(1)
                }

     * @throws \Exception
     */
    public static function onlineUsersMtl(array $member_uuids = [])
    {
        $member_uuids = array_filter($member_uuids);
        $cache_key = config('cache.key_list.online_users').md5(json_encode($member_uuids));
        $cache_data = Cache::get($cache_key);
    
        // Log::info(var_export(['$cache_data',$cache_data], true));
        if(!empty($cache_data)){
            return $cache_data;
        }

        try {
            $friends_arr_chunk = array_chunk($member_uuids, 100); //im一次取最大用户数 100
            // Log::info(var_export(['$friends_arr_chunk',$friends_arr_chunk], true));
            if(empty($friends_arr_chunk)){
                return null;
            }
            //分批取在线用户
            $im_user_status_res_all = [];
            foreach ($friends_arr_chunk as $key => $value) {

                if(empty($value)){
                    continue;
                }
                $im_user_status_res_all += UserAuth::getUsersStatusIm($value);
            }
            // Log::info(var_export(['$im_user_status_res_all',$im_user_status_res_all], true));
            $online_uuid_arr = []; //在线的好uuid
            foreach ($im_user_status_res_all as $key => $value) {
                if($value == 1 ){
                    $online_uuid_arr[$key] = 1;
                }
            }
            Cache::put($cache_key, $online_uuid_arr, config('cache.ttl'));
            // Log::info(var_export(['$online_uuid_arr',$online_uuid_arr], true));
            return $online_uuid_arr;

        } catch (\Exception $e) {
            throw new \Exception(__FILE__.',line:'.$e->getLine().','.$e->getMessage());

        }
    }

    /**
     * 返回在线的好友统计和头像
     * @param $member_uuid
     * @return 'online_count'=>$online_count 总在线人数
               'online_friends_head'=>$online_friends_head 总在线头像
     * @throws \Exception
     */
    public static function onlineUsers(string $member_uuid = '')
    {
        try {
            $res = Member::where('uuid', '=', $member_uuid)
                    ->with(['friends'])
                    ->first();
            $res_arr = $res->toArray();
            
            $online_friends_head_arr = null;
            $friends_arr = [];
            //好友uuid提取
            foreach ($res_arr['friends'] as $key => $value) {
                $friends_arr[] = $value['friend_member_uuid'];
            }
            $friends_arr_chunk = array_chunk($friends_arr, 100); //im一次取最大用户数 100
            
            //分批取在线用户
            $im_user_status_res_all = [];
            foreach ($friends_arr_chunk as $key => $value) {
                $im_user_status_res_all += UserAuth::getUsersStatusIm($value);
            }

            $friends_online_uuid_arr = []; //在线的好uuid
            foreach ($im_user_status_res_all as $key => $value) {
                if($value == 1 ){
                    $friends_online_uuid_arr[] = $key;
                }
            }

            $member_info_res = Member::whereIn('uuid',$friends_online_uuid_arr)->get();
            $member_info_res_arr = $member_info_res->toArray();
            foreach ($member_info_res_arr as $h_key => $h_value) {
                $online_friends_head_arr[$h_key] = [
                                    'uuid'=>$h_value['uuid'],
                                    'avatar_url'=>$h_value['avatar_url']];
            }

            $online_count = count($friends_online_uuid_arr);
            return [
                'online_count'=>$online_count,
                'online_friends_head'=>$online_friends_head_arr
            ];
        } catch (\Exception $e) {
            
            throw new \Exception($e->getLine().$e->getMessage());
        }
    }

    /**
     * 返回某人是否对某人关注
     * @param $member_uuid
     * @param $followed_member_uuid
     * @return num
     * @throws \Exception
     */
    public static function attention(string $member_uuid = '', string $followed_member_uuid = '')
    {
        if($member_uuid == $followed_member_uuid){
            return 1;
        }
        $follow_where = null;
        $follow_where[] = ['member_uuid', '=', $member_uuid];
        $follow_where[] = ['followed_member_uuid', '=', $followed_member_uuid];
        $follow_count = Follow::where($follow_where)->count();
        return $follow_count >=1 ? 1 : 0;
    }

    /**
     * 返回某人粉丝数
     * @param $member_uuid
     * @return num
     * @throws \Exception
     */
    public static function followCount(string $member_uuid = '')
    {
        $where[] = ['followed_member_uuid', '=', $member_uuid];
        return Follow::where($where)->count();
    }

    /**
     * 批量返回粉丝数
     * @param $member_uuid
     * @return num
     * @throws \Exception
     */
    public static function batchFollowCount(array $memberUuids = []):array
    {
        return Follow::query()->selectRaw('followed_member_uuid,count(*) as nums')
                ->whereIn('followed_member_uuid', $memberUuids)->groupBy('followed_member_uuid')
                ->get()->toArray();
    }

    /**
     * 批量某人的关注
     * @param $member_uuid 某人
     * @param $memberUuids 是否关注某些人
     * @return num
     * @throws \Exception
     */
    public static function batchAttention(string $member_uuid = '', array $followed_member_uuids = []):array
    {
        return Follow::query()->selectRaw('followed_member_uuid')
                ->where('member_uuid','=',$member_uuid)->whereIn('followed_member_uuid', $followed_member_uuids)
                ->get()->toArray();
    }

    /**
     * 获取我是否关注过给我打招呼的人的状态
     * @param $member_uuid 某人
     * @param $memberUuids 是否关注某些人
     * @return num
     * @throws \Exception
     */
    public static function batchAttentionMe(string $member_uuid = '', array $followed_member_uuids = []):array
    {
        return Follow::query()
                ->whereIn('member_uuid',$followed_member_uuids)->where('followed_member_uuid','=', $member_uuid)
                ->pluck( 'followed_member_uuid','member_uuid')
                ->toArray();
    }

    /**
     * 批量返回好友,带tab
     * @param $member_uuid
     * @return num
     * @throws \Exception
     */
    public static function batchFriend(array $memberUuids = []):array
    {
        $res =  Friend::query()->selectRaw('member_friend.tab,member_friend.friend_member_uuid,member_friend.member_uuid, members.*')->join('members','members.uuid','=','member_friend.friend_member_uuid')->whereIn('member_uuid', $memberUuids)->where('tab','<>','')->get()->toArray();
        return $res;

    }

    /**
     * @param $param
     * @param int $loginType  登录类型 1手机号码 2email 3appleid 4微信
     * @return bool
     * @throws \Exception
     */
    public static function login(array $param, int $loginType)
    {
        $res['im'] = null;
        try {
            DB::beginTransaction();

            $loginWhere = [];
            switch ($loginType){
                case 1:
                    $loginWhere['mobile'] = $param['mobile'];
                    $loginWhere['mobile_prefix'] = $param['mobile_prefix'];
                    break;
                case 2:
                    $loginWhere['email'] = $param['email'];
                    break;
                case 3:
                    $loginWhere['appleid'] = $param['appleid'];
                    break;
                case 4:
                    $loginWhere['openid'] = $param['openid'];
                    break;
                default:
                    throw new \Exception('登录异常');
                    break;
            }
            $member = Member::where($loginWhere)->first();

            if(!$member) throw new \Exception('用户未注册');

            $data = [];
            $data['ip'] = UtilService::getClientIp();
            $data['last_login_time'] = date('Y-m-d H:i:s');
            isset($param['phoneModel']) && $data['phone_model'] = $param['phoneModel'];
            isset($param['versionCode']) && $data['version_code'] = $param['versionCode'];
            isset($param['versionName']) && $data['version_name'] = $param['versionName'];

            if($member->openid && !empty($param['openid']) && $param['openid'] != $member->openid) throw new \Exception('该手机号码已绑定微信！');
            if($member->appleid && !empty($param['appleid']) && $param['appleid'] != $member->appleid) throw new \Exception('该手机号码已绑定苹果ID！');

            if(empty($member->openid) && !empty($param['openid'])) $data['openid'] = $param['openid'];
            if(empty($member->appleid) && !empty($param['appleid'])) $data['appleid'] = $param['appleid'];

            $member->update($data);
            
            //im
            $im_param = $member->toArray();
//            $res['im'] = null;
            $res['im'] = EasemobUserAuth::getToken($im_param);
            if(!isset($res['im']['access_token'])){
                $s = EasemobUserAuth::register($im_param);

                $res['im'] = EasemobUserAuth::getToken($im_param);
                if(!isset($res['im']['access_token'])){
                    $res['im'] = null;
                }
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw new \Exception($e->getLine().$e->getMessage());
        }

        return $res;
    }

    /**
     * @param array $param
     * @param int $type  =1手机号码注册 =2email注册
     * @return array
     * @throws \Exception
     */
    public static function register(array $param, int $type): array
    {

        $res['im'] = null;
        try {
            DB::beginTransaction();

            $row = $param;

            $data = [];

            $key = '';
            switch ($type){
                case 1:
                    $key = $param['mobile'];
                    $data['mobile'] = $param['mobile'];
                    $data['mobile_prefix'] = $param['mobile_prefix'];
                    break;
                case 2:
                    $key = $param['email'];
                    $data['email'] = $param['email'];
                    break;
                default:
                    throw new \Exception('刚注册方式不存在!');
            }
            $member = Member::where($data)->first();
            if($member) throw new \Exception('用户已经注册');

            if(Cache::get($key)) throw new \Exception('请勿重复操作');
            Cache::set($key, 1, 3);  //上锁 5秒
            // 会员编号
            $lastMember = Member::orderBy('no', 'desc')->first();
            $data['no'] = $lastMember ? ((int)$lastMember['no'] + 1) : 80008001;
            $data['enabled'] = 1;

            !empty($param['code']) && $data['code'] = $param['code'];
            !empty($param['inviter_uuid']) && $data['inviter_uuid'] = $param['inviter_uuid'];
            !empty($param['inviter_uuid']) && $data['inviter_time'] = date('Y-m-d H:i:s');

            !empty($param['avatar_url']) && $data['avatar_url'] = $param['avatar_url'];
            !empty($param['name']) && $data['name'] = $param['name'];
            !empty($param['nickname']) && $data['nickname'] = $param['nickname'];
            !empty($param['sex']) && $data['sex'] = $param['sex'];
            !empty($param['birthday']) && $data['birthday'] = $param['birthday'];
            !empty($param['country_uuid']) && $data['country_uuid'] = $param['country_uuid'];
            !empty($param['school_uuid']) && $data['school_uuid'] = $param['school_uuid'];

            !empty($param['appleid']) && $data['appleid'] = $param['appleid'];
            !empty($param['openid']) && $data['openid'] = $param['openid'];

            !empty($param['province_id']) && $data['province_id'] = $param['province_id'];
            !empty($param['city_id']) && $data['city_id'] = $param['city_id'];
            !empty($param['area_id']) && $data['area_id'] = $param['area_id'];
            !empty($param['lng']) && $data['lng'] = $param['lng'];
            !empty($param['lat']) && $data['lat'] = $param['lat'];
            if(!empty($param['is_old'])) {
                $data['is_old'] = $param['is_old'];
                $data['state'] = 200;
            }

            $member = Member::create($data);
            $member_save_arr = $member->toArray();
            $res['member'] = $member_save_arr;

            //用户提交内容监控埋点
            ProcessService::processData(6, $param, $member->uuid, $member->uuid);

            //发布一条官方流
            $feed_param['member_uuid'] = $member_save_arr['uuid'];
            FeedsService::officialToUserFeed($feed_param);
            
            //im
            $im_param = $member_save_arr;
//            $res['im'] = null;
            $s = EasemobUserAuth::register($im_param);
            $res['im'] = EasemobUserAuth::getToken($im_param);
            if(!isset($res['im']['access_token'])){
               $res['im'] = null;
            }

            if(!empty($param['is_old'])) {
                //TODO 新学校，建群，加成员
                $talkingResult = TalkingService::userSchoolTalkingCreateAndJoin($member->uuid, $member->school_uuid);
                if($talkingResult['code'] != 200) throw new \Exception($talkingResult['message']);

                $m_param['group_members'] = [$member->uuid];
                $com_register_group = ConfigService::find('com_register_group');
                $m_param['group_id'] = $com_register_group;
                $m_param['type'] = 3;
                $resComResult = GroupService::addMembersGroup($m_param);
                if($resComResult['code'] != 200) throw new \Exception($resComResult['code'].$resComResult['message']);
            }
            
            //和migo账号默认是好友关系  18888888888
            $migoMember = Member::where('mobile', config('sms.migo_phone'))->first();
            if($migoMember){
                Follow::create([
                    'followed_member_uuid' => $migoMember->uuid,
                    'member_uuid' => $member->uuid,
                ]);
                Follow::create([
                    'followed_member_uuid' => $member->uuid,
                    'member_uuid' => $migoMember->uuid,
                ]);

                Friend::create([
                    'member_uuid' => $migoMember->uuid,
                    'friend_member_uuid' => $member->uuid,
                ]);
                Friend::create([
                    'member_uuid' => $member->uuid,
                    'friend_member_uuid' => $migoMember->uuid,
                ]);
            }

            GatherService::add($member->uuid, '头像', '注册');
            GatherService::add($member->uuid, '名字', '注册');
            GatherService::add($member->uuid, '手机号码', '注册');
            GatherService::add($member->uuid, '性别', '注册');
            GatherService::add($member->uuid, '地区', '注册');

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw new \Exception($e->getLine().$e->getMessage());
        }

        return $res;
    }

    public static function detailByUuid($uuid){
        $member = Member::where('uuid','=',$uuid)->first();
        return $member ? $member : null;
    }

    public static function detail($id){
        $member = Member::find($id);
        return $member ? $member : null;
    }

    //签到
    public static function sign($member_id){

        try{
            DB::beginTransaction();

            $day = date('Y-m-d');

            if(SignLog::where([
                ['days', '=', $day],
                ['member_id', '=', $member_id],
            ])->exists()) throw new \Exception('今日已经签到！');

            $member = Member::where('id', $member_id)->first();

            $signDays = self::signDays($member_id);

            //添加签到记录
            SignLog::create([
                'days' => $day,
                'member_id' => $member_id,
            ]);

            //操作用户积分余额和积分等级
            $level = Level::where('value', '<=', $member->score_cash_total + $signDays['score'])->orderBy('value', 'desc')->first();
            $member->update([
                'score_level_id' => $level->id,
                'score_cash' => DB::raw('score_cash + '.$signDays['score']),
                'score_cash_total' => DB::raw('score_cash_total + '.$signDays['score']),
                'sign_days' => $signDays['sign_days'] >= 29 ? 0 : $signDays['sign_days'] + 1,
            ]);

            //记录用户积分变动日志
            Log::create([
                'member_id' => $member_id,
                'type' => 1,
                'value' => $signDays['score'],
                'score_cash' => Member::where('id', $member_id)->first()->score_cash,
                'time' => date('Y-m-d H:i:s'),
                'desc' => '签到获得积分',
            ]);

            DB::commit();
        }catch(\Exception $e){

            DB::rollBack();
            throw new \Exception($e->getMessage().$e->getLine());
        }
    }
    //签到
    public static function getScoreByTask($member_id, $task_id){

        try{
            DB::beginTransaction();

            if(TaskLog::where([
                ['task_id', '=', $task_id],
                ['member_id', '=', $member_id],
                ['created_at', '>=', date('Y-m-d')],
            ])->exists()) throw new \Exception('当前任务已经领取奖励！');

            $task = Task::find($task_id)->toArray();

            $score = 0;

            switch($task['type']){
                case 1:
                    $finished_num = Read::where([
                        ['member_id', '=', $member_id],
                        ['created_at', '>=', date('Y-m-d')],
                    ])->count('*');
                    $score = $finished_num >= $task['num'] ? $task['value'] : 0;
                    break;
                case 2:
                    $finished_num = Like::where([
                        ['member_id', '=', $member_id],
                        ['created_at', '>=', date('Y-m-d')],
                    ])->count('*');
                    $score = $finished_num >= $task['num'] ? $task['value'] : 0;
                    break;
                case 3:
//                    $finished_num = Comment::where([
//                        ['member_id', '=', $member_id],·
//                        ['created_at', '>=', date('Y-m-d')],
//                    ])->groupBy('diary_id')->count('*');

                    $finished_num = Comment::where([
                        ['member_id', '=', $member_id],
                        ['created_at', '>=', date('Y-m-d')],
                    ])->distinct('diary_id')->count('*');

                    $score = $finished_num >= $task['num'] ? $task['value'] : 0;
                    break;
                case 4:
                    $finished_num = Diary::where([
                        ['member_id', '=', $member_id],
                        ['state', '=', 9],
                        ['created_at', '>=', date('Y-m-d')],
                    ])->count('*');
                    $score = $finished_num >= $task['num'] ? $task['value'] : 0;
                    break;
                case 5:
                    $finished_num = Order::where([
                        ['member_id', '=', $member_id],
                        ['state', '>=', 1],
                        ['created_at', '>=', date('Y-m-d')],
                    ])->whereIn('type', ['3','4','5',])->count('*');
                    $score = $finished_num >= $task['num'] ? $task['value'] : 0;
                    break;
                case 6:
                    $finished_num = Share::where([
                        ['member_id', '=', $member_id],
                        ['created_at', '>=', date('Y-m-d')],
                    ])->count('*');
                    $score = $finished_num >= $task['num'] ? $task['value'] : 0;
                    break;
            }

            if($score == 0)  throw new \Exception('当前任务没有达成，请先去完成！');

            $member = Member::find($member_id);
            //操作用户积分余额和积分等级
            $level = Level::where('value', '<=', $member->score_cash_total + $score)->orderBy('value', 'desc')->first();
            $member->update([
                'score_level_id' => $level->id,
                'score_cash' => DB::raw('score_cash + '.$score),
                'score_cash_total' => DB::raw('score_cash_total + '.$score),
            ]);

            //记录用户积分变动日志
            Log::create([
                'member_id' => $member_id,
                'type' => 1,
                'value' => $score,
                'score_cash' => Member::where('id', $member_id)->first()->score_cash,
                'time' => date('Y-m-d H:i:s'),
                'desc' => '做任务获取奖励',
            ]);

            //添加领取记录
            TaskLog::create([
                'member_id' => $member_id,
                'task_id' => $task_id,
            ]);

            DB::commit();
        }catch(\Exception $e){

            DB::rollBack();
            throw new \Exception($e->getMessage().$e->getLine());
        }
    }


    public static function getHelloLimit($uuid = '', $mLevel = 0)
    {


        $limitNum = self::getHelloLimitMap($mLevel);
        $hKey = self::getHelloLimitKey($uuid, $mLevel);
        $daySec = 86400;

        if(Cache::get($hKey) > $limitNum){

            return false;
        }else{

            if(!Cache::has($hKey)){
                Cache::set($hKey,1,$daySec);
            }else{
                Cache::increment($hKey);
            }
            return true;
        }

    }


    public static function getHelloLimitMap($mLevel=0)
    {
        $levelMap = [
            1=>3,
            2=>5,
            3=>7,
            4=>10,
        ];
        if($mLevel){
            $limitNum = $levelMap[$mLevel]??3;
            return $limitNum;
        }

        return $levelMap;
    }

    public static function getHelloLimitKey($uuid='', $mLevel='')
    {
        $date = date('Ymd');

        $hKey = 'hello_limit:'.'-'.$uuid.'-'.$date.'-'.$mLevel;

        return $hKey;
    }

    public static function getSingleLimitKey($uuid='', $oUuid='')
    {
        $date = date('Ymd');
        $key = 'hello_limit:'.$uuid.'-'.$oUuid.'-'.$date;

        return $key;
    }

    public static function getSingleLimit($uuid = '', $oUuid = '' )
    {
        $key = self::getSingleLimitKey($uuid, $oUuid);
        if(Cache::has($key)){

            return false;
        }
        return true;
    }

    public static function setSingleLimit($uuid, $oUuid)
    {
        $key = self::getSingleLimitKey($uuid, $oUuid);
        $daySec = 86400;
        Cache::set($key,1,$daySec);
    }
}